﻿using CalligraphyWeb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Calligraphy.Models
{
    public class Friend
    {
        #region Data Members
        private friend data;
        public friend Data
        {
            get
            {
                if (data == null)
                    data = new friend();

                return data;
            }
            set
            {
                if (data == value) return;
                data = value;
            }
        }
        #endregion

        #region Class Methods
        public Friend()
        {
        }

        public Friend(int id, bool isLazy = true)
        {
            Get(id, isLazy);
        }

        public Friend(friend obj)
        {
            Get(obj);
        }
        public Friend Get(int id, bool isLazy = true)
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.Configuration.LazyLoadingEnabled = isLazy;
                var query = from c in db.friends
                            where c.id == id
                            select c;

                if (query.Count() > 0)
                {
                    var obj = query.FirstOrDefault();
                    return Get(obj);
                }
                else
                    return null;
            }
        }

        public Friend Get(friend obj)
        {
            if (this.data == obj) return this;

            this.data = obj;
            return this;
        }

        private long Insert()
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.friends.Add(data);
                db.SaveChanges();
                return data.id;
            }
        }

        private long Update()
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.friends.Attach(data);
                db.Entry(data).State = System.Data.EntityState.Modified;
                db.SaveChanges();
                return data.id;
            }
        }

        public long Save()
        {
            if (data.id == 0)
                return Insert();
            else
                return Update();
        }

        public long Delete()
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.friends.Remove(data);
                db.SaveChanges();
                return data.id;
            }
        }
        #endregion

        #region Static Methods
        public static ObservableCollection<friend> Get(string sortColumn = "id", bool isAsc = false,
                                                    int pageIndex = 1, int pageSize = 10,
                                                    bool isLazy = true)
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.Configuration.LazyLoadingEnabled = isLazy;
                IQueryable<friend> query = db.friends.AsQueryable();

                query = Sorting(query, sortColumn, isAsc);
                query = Paging(query, pageIndex, pageSize);

                if (query == null)
                    return new ObservableCollection<friend>();
                else
                    return new ObservableCollection<friend>(query.ToList());
            }
        }

        public static List<long> Save(Collection<friend> collection)
        {
            var result = new List<long>();
            foreach (var obj in collection)
            {
                var temp = new Friend(obj);
                result.Add(temp.Save());
            }

            return result;
        }

        public static int Delete(Collection<friend> collection)
        {
            int result = 0;
            using (calligraphyEntities db = new calligraphyEntities())
            {
                foreach (var obj in collection)
                {
                    db.friends.Remove(obj);
                    result++;
                }

                db.SaveChanges();
            }
            return result;
        }

        private static IQueryable<friend> Sorting(IQueryable<friend> query, string sortColumn = "id", bool isAsc = false)
        {
            switch (sortColumn)
            {
                case "user1":
                    query = isAsc ? query.OrderBy(o => o.userid1) : query.OrderByDescending(o => o.userid1);
                    break;
                case "user2":
                    query = isAsc ? query.OrderBy(o => o.userid2) : query.OrderByDescending(o => o.userid2);
                    break;
                case "date":
                    query = isAsc ? query.OrderBy(o => o.created) : query.OrderByDescending(o => o.created);
                    break;
                case "id":
                default:
                    query = isAsc ? query.OrderBy(o => o.id) : query.OrderByDescending(o => o.id);
                    break;
            }

            return query;
        }

        private static IQueryable<friend> Paging(IQueryable<friend> query, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 1)
                pageIndex = 0;
            else
                pageIndex--;

            return query.Skip(pageIndex * pageSize).Take(pageSize);
        }

        public static ObservableCollection<friend> Search(int userid1 = 0, int userid2 = 0,
                                        DateTime? fromDate = null, DateTime? toDate = null,
                                        string sortColumn = "id", bool isAsc = false,
                                        int pageIndex = 1, int pageSize = 10,
                                        bool isLazy = true)
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.Configuration.LazyLoadingEnabled = isLazy;
                var query = from c in db.friends
                            where (userid1 == 0 ? true : c.userid1 == userid1)
                            && (userid2 == 0 ? true : c.userid2 == userid2)
                            && (fromDate == null ? true : fromDate.Value <= c.created)
                            && (toDate == null ? true : toDate.Value >= c.created)
                            select c;

                query = Sorting(query, sortColumn, isAsc);
                query = Paging(query, pageIndex, pageSize);

                if (query.Count() > 0)
                    return new ObservableCollection<friend>(query.ToList());
                else
                    return new ObservableCollection<friend>();
            }
        } 
        #endregion
    }
}
